package com.softserveinc.interactive_board.web;

import java.util.Date;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.softserveinc.interactive_board.commons.CheckedPresentationsList;
import com.softserveinc.interactive_board.domain.Presentation;
import com.softserveinc.interactive_board.domain.User;

import com.softserveinc.interactive_board.service.PresentationService;
import com.softserveinc.interactive_board.service.UserService;
import com.softserveinc.interactive_board.validators.form.AddPresentationForm;
import com.softserveinc.interactive_board.validators.form.EditPresentationForm;
import com.softserveinc.interactive_board.validators.form.EditProfileForm;
import com.softserveinc.interactive_board.validators.form.ViewProfileForm;

@Controller
@RequestMapping("/profile")
public class ProfileController {
	private static final String VIEW_PROFILE_FILE_LOCATION = "profile/index";
	private static final String EDIT_PROFILE_FILE_LOCATION = "profile/edit/index";
	private static final String PRESENTATIONS_PROFILE_FILE_LOCATION = "profile/presentations/index";

	private static final String VIEW_PRESENTATION_FILE_LOCATION = "profile/presentations/view/index";
	private static final String EDIT_PRESENTATION_FILE_LOCATION = "profile/presentations/edit/index";
	private static final String ADD_PROFILE_FILE_LOCATION = "profile/presentations/add/index";
	private static final String PRESENTATIONS_DIR_LOCATION = "editor/saves";

	private static final String VIEW_PROFILE_ATTR_NAME = "viewProfileForm";
	private static final String EDIT_PROFILE_ATTR_NAME = "editProfileForm";
	private static final String PRESENTATIONS_LIST_PROFILE_ATTR_NAME = "checkedPresentationsList";
	private static final String EDIT_ERROR_PROFILE_ATTR_NAME = "editError";
	private static final String PRESENTOR_PROFILE_ATTR_NAME = "presentor";
	private static final String PRESENTATION_STATUS_ATTR_NAME = "presStatusesAttr";

	private static final String ADD_PRESENTATION_ATTR_NAME = "addPresentationForm";
	private static final String EDIT_PRESENTATION_ATTR_NAME = "editPresentationForm";
	private static final String PRESENTATION_ATTR_NAME = "presentation";
	private static final String PRESENTATION_DIR_ATTR_NAME = "presentation_dir";

	@RequestMapping(method = RequestMethod.GET)
	public String view() {
		return "redirect:/profile/";
	}

	// -----------------------View---------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/")
	public String view(Model model) {
		String name = SecurityContextHolder.getContext().getAuthentication()
				.getName();
		if (name.equals("_anonymous"))
			return "redirect:/";
		User user = this.userService.getUser(name);
		model.addAttribute(VIEW_PROFILE_ATTR_NAME, new ViewProfileForm(user));
		boolean presentor = (user.getUserType().getId() == 1);
		model.addAttribute(PRESENTOR_PROFILE_ATTR_NAME, presentor);
		return VIEW_PROFILE_FILE_LOCATION;

	}

	// -----------------------Edit---------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/edit")
	public String edit(Model model) {
		String name = SecurityContextHolder.getContext().getAuthentication()
				.getName();
		if (name.equals("_anonymous"))
			return "redirect:/";
		User user = this.userService.getUser(name);
		model.addAttribute(EDIT_PROFILE_ATTR_NAME, new EditProfileForm(user));
		model.addAttribute(EDIT_ERROR_PROFILE_ATTR_NAME, false);
		return EDIT_PROFILE_FILE_LOCATION;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/edit")
	public String edit(Model model, @Valid final EditProfileForm form,
			final BindingResult result) {
		if (result.hasErrors()) {
			model.addAttribute(EDIT_PROFILE_ATTR_NAME,
					new EditProfileForm(form.getUser()));
			model.addAttribute(EDIT_ERROR_PROFILE_ATTR_NAME, true);
			return EDIT_PROFILE_FILE_LOCATION;
		}
		this.userService.updateUser(form.getUser());
		return VIEW_PROFILE_FILE_LOCATION;
	}

	// -----------------------Presentations---------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/presentation")
	public String presentations() {
		return "redirect:/profile/presentations/";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/presentations/")
	public String presentations(Model model) {
		String name = SecurityContextHolder.getContext().getAuthentication()
				.getName();
		if (name.equals("_anonymous"))
			return "redirect:/";
		User user = this.userService.getUser(name);
		boolean presentor = (user.getUserType().getId() == 1);
		if (!presentor)
			return "redirect:/";
		List<Presentation> presentations = this.presentationService
				.getPresentationsByPresentorId(user.getId().intValue());
		model.addAttribute(PRESENTATIONS_LIST_PROFILE_ATTR_NAME,
				new CheckedPresentationsList(presentations));
		return PRESENTATIONS_PROFILE_FILE_LOCATION;

	}

	// -----------------------Show---------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/presentations/show")
	public String presentationShow(
			@RequestParam("presentation_id") Long presId, Model model) {
		Presentation presentation = new Presentation(presId);
		model.addAttribute(PRESENTATION_ATTR_NAME, presentation);
		model.addAttribute(PRESENTATION_DIR_ATTR_NAME,
				PRESENTATIONS_DIR_LOCATION);
		return VIEW_PRESENTATION_FILE_LOCATION;
	}

	// ----------------------------Add-------------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "presentations/add")
	public String presentationAdd(Model model) {
		model.addAttribute(ADD_PRESENTATION_ATTR_NAME,
				new AddPresentationForm());
		model.addAttribute(PRESENTATION_STATUS_ATTR_NAME,
				this.presentationService.getPresentationStatuses());
		return ADD_PROFILE_FILE_LOCATION;
	}

	@RequestMapping(method = RequestMethod.POST, value = "presentations/add")
	public String presentationAdd(Model model,
			@Valid final AddPresentationForm form, final BindingResult result) {
		if (result.hasErrors()) {
			return ADD_PROFILE_FILE_LOCATION;
		}
		String name = SecurityContextHolder.getContext().getAuthentication()
				.getName();
		if (name.equals("_anonymous"))
			return "redirect:/";
		User user = this.userService.getUser(name);
		form.setUserId(user.getId());
		form.setDate(new Date().toString());
		// form.setId(id); // need disscusion
		this.presentationService.addPresentation(form.getPresentation());
		return PRESENTATIONS_PROFILE_FILE_LOCATION;
	}

	// -----------------------Delete---------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/presentations/delete")
	public String presentationDelete(
			@RequestParam("presentation_id") Long presId) {
		Presentation pres = new Presentation(presId);
		this.presentationService.deletePresentation(pres);
		return "redirect:/profile/presentations";
	}

	// ----------------------------Edit-------------------------------------
	@RequestMapping(method = RequestMethod.GET, value = "/presentations/edit")
	public String presentationEdit(
			@RequestParam("presentation_id") Long presId, Model model) {
		Presentation pres = new Presentation(presId);
		model.addAttribute(EDIT_PRESENTATION_ATTR_NAME,
				new EditPresentationForm(pres));
		return EDIT_PRESENTATION_FILE_LOCATION;
	}

	private UserService userService;
	private PresentationService presentationService;

	@Autowired
	@Qualifier("interactiveBoardServiceImpl")
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Autowired
	@Qualifier("PresentationServiceImpl")
	public void setPresentationService(PresentationService presentationService) {
		this.presentationService = presentationService;
	}
}
